Java 中动态 JSON 对象的使用

您所在的位置:网站首页 jackson json解析 Java 中动态 JSON 对象的使用

Java 中动态 JSON 对象的使用

2023-12-10 05:38| 来源: 网络整理| 查看: 265

最主流的 JSON 处理库是 fasterxml 的Jaskson和 google 的Gson等。(其他的还有比如com.alibaba:fastjson或net.sf.json-lib:json-lib等)

在已有实体类结构的情况下,现有的 JSON 库可以轻松地把 JSON 文本反序列为实体类。

// Jackson 序列化 com.fasterxml.jackson.databind.ObjectMapper#writeValueAsString // Jackson 反序列化 com.fasterxml.jackson.databind.ObjectMapper#readValue(java.lang.String, java.lang.Class) // Gson 序列化 com.google.gson.Gson#toJson(java.lang.Object) // Gson 反序列化 com.google.gson.Gson#fromJson(java.lang.String, java.lang.Class)

但是如果未知实体类的结构,那么一般操作方式就是直接把 JSON 文本转成java.util.Map,或者JSON 库本身的JSON对象模型。

一、Jackson 1. 基本模型

Jaskson的动态JSON对象模型如下图所示:

顶层是TreeNode和JsonNode,其可直接使用的子类主要分为两种,分别是ContainerNode和ValueNode:

其中ValueNode的众多子类是 JSON 中的各种值类型,例如某个key的value是一个字符串(TextNode)、或者整型(IntNode)、或者null(NullNode)。或者一个单独的值也是符合 JSON 结构规范的。 而ContainerNode则是最常见的 JSON 结构了,主要分为ObjectNode和ArrayNode,分别对应两个顶层结构:花括号({})与方括号([])。

使用方法:

使用com.fasterxml.jackson.databind.ObjectMapper#readTree(java.lang.String)方法把 JSON 文本解析成JsonNode对象。当然这个方法还有其他重载可以接受不同参数,此处不再赘述。 使用com.fasterxml.jackson.databind.node.JsonNodeFactory#*Node方法可以创建各种 Node 对象。ArrayNode/ObjectNode/ObjectMapper 也可以创建各种 Node 对象,是通过调用其内部的JsonNodeFactory实例完成的。 2. 示例

以如下的 JSON 文本举例:

[ { "name": "zhangsan", "age": 24 }, { "name": "lisi", "age": 30 } ]

先在项目的Gradle文件中导入依赖:

implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0-rc2'

引入jackson-databind即可,jackson-databind会自己引入对应的jackson-core和jackson-annotations。

然后直接上代码片段:

import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.IntNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; public class JacksonTest { /** * json: * [ * { * "name": "zhangsan", * "age": 24 * }, * { * "name": "lisi", * "age": 30 * } * ] * */ private static final String json = "[{\"name\": \"zhangsan\",\"age\": 24},{\"name\": \"lisi\",\"age\": 30}]"; private static ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) { JsonNode jsonNode = null; try { // 把 JSON 文本解析成 JsonNode 对象 jsonNode = objectMapper.readTree(json); } catch (JsonProcessingException e) { e.printStackTrace(); } // 该 JSON 文本最顶层的 JSON 模型是一个 ArrayNode ArrayNode arrayNode = (ArrayNode) jsonNode; // ArrayNode 的第一项是一个 ObjectNode ObjectNode objectNode = (ObjectNode) arrayNode.get(0); // 该 objectNode 中 key 为 "name" 的值 TextNode name = (TextNode) objectNode.get("name"); // 该 objectNode 中 key 为 "age" 的值 IntNode age = (IntNode) objectNode.get("age"); // 往 ObjectNode 中添加键值对,或者修改 value objectNode.put("city", "beijing"); objectNode.put("age", 25); // 往 ArrayNode 中删除一项,或者添加一项 arrayNode.remove(1); arrayNode.add("a new item"); // JsonNodeFactory.instance.*Node 方法可以创建各种 Node 对象 arrayNode.add(JsonNodeFactory.instance.nullNode()); // 直接 print 可以打印 JSON 文本 System.out.println(jsonNode); // ArrayNode/ObjectNode/ObjectMapper 也可以创建各种 Node 对象 TextNode textNode1 = arrayNode.textNode("test"); ArrayNode arrayNode1 = objectMapper.createArrayNode(); System.out.println(textNode1); } }

参考: https://www.baeldung.com/jackson-mapping-dynamic-object https://www.baeldung.com/jackson-json-node-tree-model

二、Gson 1. 基本模型

相比Jackson,Gson的动态JSON对象模型就比较简洁:

顶层是JsonElement,其可直接使用的子类主要分为四种:JsonObject、JsonArray、JsonNull、JsonPrimitive。前三个可以从字面理解,JsonPrimitive则是各种基本值类型,大概类似于 Jackson 的ValueNode除去NullNode。

注意gson的com.google.gson.JsonObject 与 json-lib的net.sf.json.JSONObject 和 fastjson的com.alibaba.fastjson.JSONObject 区分一下,不要用混了。

使用方法:

使用com.google.gson.JsonParser#parseString方法把 JSON 文本解析成JsonElement对象。当然这个方法还有其他类似的比如parseReader,此处不再赘述。 JsonElement的各个子类都可以直接new出来,其中JsonNull则推荐使用JsonNull.INSTANCE。 2. 示例

依旧以上面的 JSON 文本举例,先在项目的Gradle文件中导入依赖:

implementation 'com.google.code.gson:gson:2.8.6'

然后直接上代码片段:

import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; public class GsonTest { /** * json: * [ * { * "name": "zhangsan", * "age": 24 * }, * { * "name": "lisi", * "age": 30 * } * ] * */ private static final String json = "[{\"name\": \"zhangsan\",\"age\": 24},{\"name\": \"lisi\",\"age\": 30}]"; public static void main(String[] args) { // 把 JSON 文本解析成 JsonElement 对象 JsonElement jsonElement = JsonParser.parseString(json); // 该 JSON 文本最顶层的 JSON 模型是一个 JsonArray JsonArray jsonArray = (JsonArray) jsonElement; // JsonArray 的第一项是一个 JsonObject JsonObject jsonObject = (JsonObject) jsonArray.get(0); // 该 JsonObject 中 key 为 "name" 的值 JsonPrimitive name = (JsonPrimitive) jsonObject.get("name"); // 该 JsonObject 中 key 为 "age" 的值 JsonPrimitive age = (JsonPrimitive) jsonObject.get("age"); // 往 JsonObject 中添加键值对,或者修改 value jsonObject.addProperty("city", "beijing"); jsonObject.addProperty("age", 25); // 往 JsonArray 中删除一项,或者添加一项 jsonArray.remove(1); jsonArray.add("first new item"); // 各种 Json 模型对象可以直接 new 出来,null 则推荐 JsonNull.INSTANCE jsonArray.add(new JsonPrimitive("second new item")); // 直接 print 可以打印 JSON 文本 System.out.println(jsonElement); } } 三、总结

介绍了Jaskson和Gson的动态JSON对象的模型与基本使用方式,至于这两个 JSON 库基础的序列化与反序列化、或者动态JSON对象更进一步的使用方式 可以自己读一下二者的文档(Gson Jackson)。个人虽然平时用Jackson比较多,但是感觉Gson更加简洁。

TODO 有空更一篇 JsonPath 的介绍。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3